package com.gvtv.main.db;

import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.sql.DataSource;

import org.apache.log4j.Logger;

import com.gvtv.main.exception.ExecuteException;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class ConnectionManager {

	private static Logger logger = Logger.getLogger(ConnectionManager.class);
	
	private static Map<String, DataSource> dataSourceMap = new ConcurrentHashMap<String, DataSource>();
	private static byte[] lock = new byte[0];
	
	public static Connection getConnection(String id, String driver, String url, String username, String password) throws ExecuteException{
		Connection connection = null;
		try {
			if(dataSourceMap.get(id)==null){
				ComboPooledDataSource cpds = new ComboPooledDataSource();
				cpds.setDriverClass(driver);
				cpds.setJdbcUrl(url);
				cpds.setUser(username);
				cpds.setPassword(password);
				cpds.setInitialPoolSize(5);
				cpds.setMinPoolSize(5);
				cpds.setMaxPoolSize(20);
				cpds.setMaxIdleTime(30);
				synchronized(lock){
					if(dataSourceMap.get(id)==null){
						dataSourceMap.put(id, cpds);
					}
				}
			}
			connection = dataSourceMap.get(id).getConnection();
		} catch (PropertyVetoException e) {
			logger.error("加载驱动出错."+e);
			throw new ExecuteException("加载驱动出错", e);
		} catch (SQLException e) {
			logger.error("获取数据连接出错. "+e);
			throw new ExecuteException("获取数据连接出错", e);
		}
		return connection;
	}
	
	public static void fillStatement(PreparedStatement stmt, Object... params) throws SQLException {
		ParameterMetaData pmd = null;
		pmd = stmt.getParameterMetaData();
		int stmtCount = pmd.getParameterCount();
		int paramsCount = params == null ? 0 : params.length;
		if (stmtCount != paramsCount) {
			throw new SQLException("Wrong number of parameters: expected " + stmtCount + ", was given " + paramsCount);
		}
		if (params == null) {
			return;
		}
		for (int i = 0; i < params.length; i++) {
			if (params[i] != null) {
				stmt.setObject(i + 1, params[i]);
			} else {
				int sqlType = Types.VARCHAR;
				try {
					sqlType = pmd.getParameterType(i + 1);
				} catch (SQLException e) {
				}
				stmt.setNull(i + 1, sqlType);
			}
		}
	}
}
